//
//  FSMediaPicker.m
//  Pods
//
//  Created by Wenchao Ding on 2/3/15.
//  f33chobits@gmail.com
//

#import "FSMediaPicker.h"
#import<AssetsLibrary/AssetsLibrary.h>
#import<AVFoundation/AVCaptureDevice.h>
#import<AVFoundation/AVMediaFormat.h>
#import <UIKit/UIKit.h>
#import <MobileCoreServices/MobileCoreServices.h>
#import <objc/runtime.h>
#define SCALE_EDIT_Y_POS 100
#define LocalizedString(key) \
NSLocalizedStringWithDefaultValue(key, @"FSMediaPicker", [NSBundle bundleWithPath:[[[NSBundle mainBundle] bundlePath] stringByAppendingPathComponent:@"FSMediaPicker.bundle"]], key, nil)

#define kTakePhotoString LocalizedString(@"Take photo")
#define kSelectPhotoFromLibraryString LocalizedString(@"Select photo from photo library")
#define kRecordVideoString LocalizedString(@"Record video")
#define kSelectVideoFromLibraryString LocalizedString(@"Select video from photo library")
#define kCancelString LocalizedString(@"Cancel")

NSString const * UIImagePickerControllerCircularEditedImage = @" UIImagePickerControllerCircularEditedImage;";
NSString const * UIImagePickerControllerScaleEditedImage = @" UIImagePickerControllerScaleEditedImage;";

@interface FSMediaPicker ()<UIActionSheetDelegate, UIImagePickerControllerDelegate, UINavigationControllerDelegate>

- (UIWindow *)currentVisibleWindow;
- (UIViewController *)currentVisibleController;

- (void)delegatePerformFinishWithMediaInfo:(NSDictionary *)mediaInfo;
- (void)delegatePerformWillPresentImagePicker:(UIImagePickerController *)imagePicker;
- (void)delegatePerformCancel;

- (void)showAlertController:(UIView *)view;
- (void)showActionSheet:(UIView *)view;

- (void)takePhotoFromCamera;
- (void)takePhotoFromPhotoLibrary;
- (void)takeVideoFromCamera;
- (void)takeVideoFromPhotoLibrary;

@end

@implementation FSMediaPicker

#pragma mark - Life Cycle

- (instancetype)initWithDelegate:(id<FSMediaPickerDelegate>)delegate
{
        self = [super init];
        if (self) {
                self.delegate = delegate;
        }
        return self;
}

#pragma mark - Public

- (void)show
{
        [self showFromView:self.currentVisibleController.view];
}

- (void)showFromView:(UIView *)view
{
        if ([UIAlertController class]) {
                [self showAlertController:view];
        } else {
                [self showActionSheet:view];
        }
}

#pragma mark - UIActionSheet Delegate

- (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex
{
        if (buttonIndex == actionSheet.cancelButtonIndex) {
                return;
        }
        switch (buttonIndex) {
                case 0:
                {
                        if (self.mediaType == FSMediaTypePhoto || self.mediaType == FSMediaTypeAll) {
                                [self takePhotoFromCamera];
                        } else if (self.mediaType == FSMediaTypeVideo) {
                                [self takeVideoFromCamera];
                        }
                        break;
                }
                case 1:
                {
                        if (self.mediaType == FSMediaTypePhoto || self.mediaType == FSMediaTypeAll) {
                                [self takePhotoFromPhotoLibrary];
                        } else if (self.mediaType == FSMediaTypeVideo) {
                                [self takeVideoFromPhotoLibrary];
                        }
                        break;
                }
                case 2:
                {
                        if (self.mediaType == FSMediaTypeAll) {
                                [self takeVideoFromCamera];
                        }
                        break;
                }
                case 3:
                {
                        if (self.mediaType == FSMediaTypeAll) {
                                [self takeVideoFromPhotoLibrary];
                        }
                        break;
                }
                default:
                        break;
        }
}

- (void)actionSheet:(UIActionSheet *)actionSheet willDismissWithButtonIndex:(NSInteger)buttonIndex
{
        if (buttonIndex == actionSheet.cancelButtonIndex) {
                [self delegatePerformCancel];
        }
}

#pragma mark - UIImagePickerController Delegate

- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
        [picker.presentingViewController dismissViewControllerAnimated:YES completion:nil];
        [self delegatePerformFinishWithMediaInfo:info];
}

- (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker
{
        [picker.presentingViewController dismissViewControllerAnimated:YES completion:nil];
        [self delegatePerformCancel];
}

- (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated
{
	if (self.mediaType == FSMediaTypePhoto) {
		if ([viewController isKindOfClass:NSClassFromString(@"PLUIImageViewController")] && self.editMode == FSEditModeCircular && [navigationController.viewControllers count] == 3) {
			CGFloat screenHeight = [[UIScreen mainScreen] bounds].size.height;
			
			UIView *plCropOverlay = [[viewController.view.subviews objectAtIndex:1] subviews][0];
			
			plCropOverlay.hidden = YES;
			
			CGFloat position = 0;
			
			CGFloat width = plCropOverlay.bounds.size.width;
			CGFloat height = plCropOverlay.bounds.size.height;
			
			position = (height - width) * 0.5;
			
			BOOL isIpad = UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad;
			
			CAShapeLayer *circleLayer = [CAShapeLayer layer];
			
			CGFloat diameter = isIpad ? MAX(plCropOverlay.frame.size.width, plCropOverlay.frame.size.height) : MIN(plCropOverlay.frame.size.width, plCropOverlay.frame.size.height);
			
			UIBezierPath *circlePath = [UIBezierPath bezierPathWithOvalInRect:
						    CGRectMake(0.0f, position, diameter, diameter)];
			[circlePath setUsesEvenOddFillRule:YES];
			[circleLayer setPath:[circlePath CGPath]];
			[circleLayer setFillColor:[[UIColor clearColor] CGColor]];
			
			CGFloat bottomBarHeight = isIpad ? 51 : 72;
			
			UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:CGRectMake(0, 0, diameter, screenHeight - bottomBarHeight) cornerRadius:0];
			[path appendPath:circlePath];
			[path setUsesEvenOddFillRule:YES];
			
			CAShapeLayer *fillLayer = [CAShapeLayer layer];
			fillLayer.name = @"fillLayer";
			fillLayer.path = path.CGPath;
			fillLayer.fillRule = kCAFillRuleEvenOdd;
			fillLayer.fillColor = [UIColor blackColor].CGColor;
			fillLayer.opacity = 0.5;
			[viewController.view.layer addSublayer:fillLayer];
			
			
			//                if (!isIpad) {
			//                        UILabel *moveLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 10, 320, 50)];
			//                        [moveLabel setText:@"Move and Scale"];
			//                        [moveLabel setTextAlignment:NSTextAlignmentCenter];
			//                        [moveLabel setTextColor:[UIColor whiteColor]];
			//                        [viewController.view addSubview:moveLabel];
			//                }
			
		}
		else if ([viewController isKindOfClass:NSClassFromString(@"PLUIImageViewController")] && self.editMode == FSEditModeClear && [navigationController.viewControllers count] == 3)
		{
			UIView *plCropOverlay = [[viewController.view.subviews objectAtIndex:1] subviews][0];
			
			plCropOverlay.hidden = YES;
		}
		else if ([viewController isKindOfClass:NSClassFromString(@"PLUIImageViewController")] && self.editMode == FSEditModeScaleEdit && [navigationController.viewControllers count] == 3) {
			CGFloat screenHeight = [[UIScreen mainScreen] bounds].size.height;
			
			UIView *plCropOverlay = [[viewController.view.subviews objectAtIndex:1] subviews][0];
			
			plCropOverlay.hidden = YES;
			
			CGFloat position = 0;
			
			CGFloat width = plCropOverlay.bounds.size.width;
			CGFloat height = plCropOverlay.bounds.size.height;
			
			position = (height - width) * 0.5;
			
			BOOL isIpad = UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad;
			
			CAShapeLayer *scaleLayer = [CAShapeLayer layer];
			
			UIBezierPath *scalePath = [UIBezierPath bezierPathWithOvalInRect:
						   CGRectMake(0.0f, position, width, width)];
			
			if (!CGSizeEqualToSize(self.editScale, CGSizeZero) && self.editScale.width > 0 && self.editScale.height > 0)
			{
				CGFloat pathWidth = width;
				CGFloat pathHeight = width * (self.editScale.height / self.editScale.width);
				position += (width - pathHeight) * 0.5;
				scalePath = [UIBezierPath bezierPathWithRect:CGRectMake(0.0, position, pathWidth, pathHeight)];
			}
			
			[scalePath setUsesEvenOddFillRule:YES];
			[scaleLayer setPath:[scalePath CGPath]];
			[scaleLayer setFillColor:[[UIColor clearColor] CGColor]];
			
			CGFloat bottomBarHeight = isIpad ? 51 : 72;
			
			UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:CGRectMake(0, 0, width, screenHeight - bottomBarHeight) cornerRadius:0];
			[path appendPath:scalePath];
			[path setUsesEvenOddFillRule:YES];
			
			CAShapeLayer *fillLayer = [CAShapeLayer layer];
			fillLayer.name = @"fillLayer";
			fillLayer.path = path.CGPath;
			fillLayer.fillRule = kCAFillRuleEvenOdd;
			fillLayer.fillColor = [UIColor blackColor].CGColor;
			fillLayer.opacity = 0.5;
			[viewController.view.layer addSublayer:fillLayer];
			
			
			//		if (!isIpad) {
			//			UILabel *moveLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 10, 320, 50)];
			//			[moveLabel setText:@"Move and Scale"];
			//			[moveLabel setTextAlignment:NSTextAlignmentCenter];
			//			[moveLabel setTextColor:[UIColor whiteColor]];
			//			[viewController.view addSubview:moveLabel];
			//		}
			
		}
	}
	
}

#pragma mark - Setter & Getter

- (UIWindow *)currentVisibleWindow
{
        NSEnumerator *frontToBackWindows = [UIApplication.sharedApplication.windows reverseObjectEnumerator];
        for (UIWindow *window in frontToBackWindows){
                BOOL windowOnMainScreen = window.screen == UIScreen.mainScreen;
                BOOL windowIsVisible = !window.hidden && window.alpha > 0;
                BOOL windowLevelNormal = window.windowLevel == UIWindowLevelNormal;
                if (windowOnMainScreen && windowIsVisible && windowLevelNormal) {
                        return window;
                }
        }
        return [[[UIApplication sharedApplication] delegate] window];
}

- (UIViewController *)currentVisibleController
{
        UIViewController *topController = self.currentVisibleWindow.rootViewController;
        while (topController.presentedViewController) {
                topController = topController.presentedViewController;
        }
        return topController;
}

#pragma mark - Private

- (void)delegatePerformFinishWithMediaInfo:(NSDictionary *)mediaInfo
{
        if ([[mediaInfo allKeys] containsObject:UIImagePickerControllerEditedImage]) {
                NSMutableDictionary *dic = [NSMutableDictionary dictionaryWithDictionary:mediaInfo];
		if (self.editMode == FSEditModeScaleEdit)
		{
			dic[UIImagePickerControllerScaleEditedImage] = [dic[UIImagePickerControllerEditedImage] scaleImageWithScale:self.editScale];
		}
		else
		{
			dic[UIImagePickerControllerCircularEditedImage] = [dic[UIImagePickerControllerEditedImage] circularImage];
		}
		
                mediaInfo = [NSDictionary dictionaryWithDictionary:dic];
        }
        
        if (![[mediaInfo allKeys] containsObject:UIImagePickerControllerReferenceURL])
        {
                NSMutableDictionary *dic = [NSMutableDictionary dictionaryWithDictionary:mediaInfo];
                dic[UIImagePickerControllerReferenceURL] = [NSURL URLWithString:@"assets-library://asset/asset.JPG?id=000--00&ext=JPG"];
                mediaInfo = [NSDictionary dictionaryWithDictionary:dic];
                
                UIImageWriteToSavedPhotosAlbum(mediaInfo.originalImage, nil, nil, NULL);
        }
        
        if (_finishBlock) {
                _finishBlock(self,mediaInfo);
        } else if (_delegate && [_delegate respondsToSelector:@selector(mediaPicker:didFinishWithMediaInfo:)]) {
                [_delegate mediaPicker:self didFinishWithMediaInfo:mediaInfo];
        }
        
        
        

}

- (void)delegatePerformWillPresentImagePicker:(UIImagePickerController *)imagePicker
{
        if (_willPresentImagePickerBlock) {
                _willPresentImagePickerBlock(self,imagePicker);
        } else if (_delegate && [_delegate respondsToSelector:@selector(mediaPicker:willPresentImagePickerController:)]) {
                [_delegate mediaPicker:self willPresentImagePickerController:imagePicker];
        }
}

- (void)delegatePerformCancel
{
        if (_cancelBlock) {
                _cancelBlock(self);
        } else if (_delegate && [_delegate respondsToSelector:@selector(mediaPickerDidCancel:)]) {
                [_delegate mediaPickerDidCancel:self];
        }
}

- (void)showActionSheet:(UIView *)view
{
        UIActionSheet *actionSheet = [[UIActionSheet alloc] init];
        actionSheet.mediaPicker = self;
        switch (self.mediaType) {
                case FSMediaTypePhoto:
                {
                        [actionSheet addButtonWithTitle:kTakePhotoString];
                        [actionSheet addButtonWithTitle:kSelectPhotoFromLibraryString];
                        [actionSheet addButtonWithTitle:kCancelString];
                        actionSheet.cancelButtonIndex = 2;
                        break;
                }
                case FSMediaTypeVideo:
                {
                        [actionSheet addButtonWithTitle:kRecordVideoString];
                        [actionSheet addButtonWithTitle:kSelectVideoFromLibraryString];
                        [actionSheet addButtonWithTitle:kCancelString];
                        actionSheet.cancelButtonIndex = 2;
                        break;
                }
                case FSMediaTypeAll:
                {
                        [actionSheet addButtonWithTitle:kTakePhotoString];
                        [actionSheet addButtonWithTitle:kSelectPhotoFromLibraryString];
                        [actionSheet addButtonWithTitle:kRecordVideoString];
                        [actionSheet addButtonWithTitle:kSelectVideoFromLibraryString];
                        [actionSheet addButtonWithTitle:kCancelString];
                        actionSheet.cancelButtonIndex = 4;
                        break;
                }
                default:
                        break;
        }
        actionSheet.delegate = self;
        [actionSheet showFromRect:view.bounds inView:view animated:YES];
}

- (void)showAlertController:(UIView *)view
{
        UIAlertController *alertController = [[UIAlertController alloc] init];
        alertController.mediaPicker = self;
        switch (self.mediaType) {
                case FSMediaTypePhoto:
                {
                        [alertController addAction:[UIAlertAction actionWithTitle:kTakePhotoString style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) {
                                [self takePhotoFromCamera];
                        }]];
                        [alertController addAction:[UIAlertAction actionWithTitle:kSelectPhotoFromLibraryString style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) {
                                [self takePhotoFromPhotoLibrary];
                        }]];
                        break;
                }
                case FSMediaTypeVideo:
                {
                        [alertController addAction:[UIAlertAction actionWithTitle:kRecordVideoString style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) {
                                [self takeVideoFromCamera];
                        }]];
                        [alertController addAction:[UIAlertAction actionWithTitle:kSelectVideoFromLibraryString style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) {
                                [self takeVideoFromPhotoLibrary];
                        }]];
                        break;
                }
                case FSMediaTypeAll:
                {
                        [alertController addAction:[UIAlertAction actionWithTitle:kTakePhotoString style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) {
                                [self takePhotoFromCamera];
                        }]];
                        [alertController addAction:[UIAlertAction actionWithTitle:kSelectPhotoFromLibraryString style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) {
                                [self takePhotoFromPhotoLibrary];
                        }]];
                        [alertController addAction:[UIAlertAction actionWithTitle:kRecordVideoString style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) {
                                [self takeVideoFromCamera];
                        }]];
                        [alertController addAction:[UIAlertAction actionWithTitle:kSelectVideoFromLibraryString style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) {
                                [self takeVideoFromPhotoLibrary];
                        }]];
                        break;
                }
                default:
                        break;
        }
        [alertController addAction:[UIAlertAction actionWithTitle:kCancelString style:UIAlertActionStyleCancel handler:^(UIAlertAction *action) {
                [self delegatePerformCancel];
        }]];
        alertController.popoverPresentationController.sourceView = view;
        alertController.popoverPresentationController.sourceRect = view.bounds;
        [self.currentVisibleController presentViewController:alertController animated:YES completion:nil];
}

- (void)takePhotoFromCamera
{
        if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera] && [self checkCameraAuth]) {
                UIImagePickerController *imagePicker = [UIImagePickerController new];
                imagePicker.allowsEditing = (_editMode != FSEditModeNone && _editMode != FSEditModeClear);
                imagePicker.delegate = self;
                imagePicker.sourceType = UIImagePickerControllerSourceTypeCamera;
                imagePicker.showsCameraControls = YES;
                imagePicker.mediaTypes = @[(NSString *)kUTTypeImage,(NSString *)kUTTypePNG];
                imagePicker.mediaPicker = self;
                [self delegatePerformWillPresentImagePicker:imagePicker];
                [self.currentVisibleController presentViewController:imagePicker animated:YES completion:nil];
        }
}

- (void)takePhotoFromPhotoLibrary
{
        if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypePhotoLibrary] && [self checkPhotoAuth]) {
                UIImagePickerController *imagePicker = [UIImagePickerController new];
                imagePicker.allowsEditing = _editMode != FSEditModeNone;
                imagePicker.delegate = self;
                imagePicker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
                imagePicker.mediaTypes = @[(NSString *)kUTTypeImage];
                imagePicker.mediaPicker = self;
                [self delegatePerformWillPresentImagePicker:imagePicker];
                [self.currentVisibleController presentViewController:imagePicker animated:YES completion:nil];
        }
}

- (void)takeVideoFromCamera
{
        if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera] && [self checkCameraAuth]) {
                UIImagePickerController *imagePicker = [UIImagePickerController new];
                imagePicker.allowsEditing = _editMode != FSEditModeNone;
                imagePicker.delegate = self;
                imagePicker.sourceType = UIImagePickerControllerSourceTypeCamera;
                imagePicker.mediaTypes = @[(NSString *)kUTTypeMovie];
                imagePicker.mediaPicker = self;
                [self delegatePerformWillPresentImagePicker:imagePicker];
                [self.currentVisibleController presentViewController:imagePicker animated:YES completion:nil];
        }
}

- (void)takeVideoFromPhotoLibrary
{
        if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypePhotoLibrary] && [self checkPhotoAuth]) {
                UIImagePickerController *imagePicker = [UIImagePickerController new];
                imagePicker.allowsEditing = _editMode != FSEditModeNone;
                imagePicker.delegate = self;
                imagePicker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
                imagePicker.mediaTypes = @[(NSString *)kUTTypeMovie];
                imagePicker.mediaPicker = self;
                [self delegatePerformWillPresentImagePicker:imagePicker];
                [self.currentVisibleController presentViewController:imagePicker animated:YES completion:nil];
        }
}

- (BOOL)checkPhotoAuth
{
        ALAuthorizationStatus author = [ALAssetsLibrary authorizationStatus];
        
        if(author == ALAuthorizationStatusRestricted || author == ALAuthorizationStatusDenied){
                
                //无权限
                NSError *error = [NSError errorWithDomain:@"FSMediaPicker" code:-1 userInfo:@{NSLocalizedDescriptionKey : @"照片未授权", NSLocalizedRecoverySuggestionErrorKey : @"请授权橙子VR访问您的照片"}];
                if (self.delegate && [self.delegate respondsToSelector:@selector(mediaPicker:failedAuth:)])
                {
                        [self.delegate mediaPicker:self failedAuth:error];
                }
                else if (self.failedPresentImagePickerBlock)
                {
                        self.failedPresentImagePickerBlock(self,error);
                }
                return NO;
        }
        return YES;
}
- (BOOL)checkCameraAuth
{
        AVAuthorizationStatus authStatus = [AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeVideo];
        
        if(authStatus == AVAuthorizationStatusRestricted || authStatus ==AVAuthorizationStatusDenied){
                
                //无权限
                NSError *error = [NSError errorWithDomain:@"FSMediaPicker" code:-2 userInfo:@{NSLocalizedDescriptionKey : @"相机未授权", NSLocalizedRecoverySuggestionErrorKey : @"请授权橙子VR访问您的相机"}];
                if (self.delegate && [self.delegate respondsToSelector:@selector(mediaPicker:failedAuth:)])
                {
                        [self.delegate mediaPicker:self failedAuth:error];
                }
                else if (self.failedPresentImagePickerBlock)
                {
                        self.failedPresentImagePickerBlock(self,error);
                }
                return NO;
        }
        return YES;
}
@end

@implementation NSDictionary (FSMediaPicker)

- (UIImage *)originalImage
{
        if ([self.allKeys containsObject:UIImagePickerControllerOriginalImage]) {
                return self[UIImagePickerControllerOriginalImage];
        }
        return nil;
}

- (UIImage *)editedImage
{
        if ([self.allKeys containsObject:UIImagePickerControllerEditedImage]) {
                return self[UIImagePickerControllerEditedImage];
        }
        return nil;
}
- (UIImage *)scaleEditedImage
{
	if ([self.allKeys containsObject:UIImagePickerControllerScaleEditedImage]) {
		return self[UIImagePickerControllerScaleEditedImage];
	}
	return nil;
}

- (UIImage *)circularEditedImage
{
        if ([self.allKeys containsObject:UIImagePickerControllerCircularEditedImage]) {
                return self[UIImagePickerControllerCircularEditedImage];
        }
        return nil;
}

- (NSURL *)imageURL
{
        if ([self.allKeys containsObject:UIImagePickerControllerReferenceURL])
        {
                return self[UIImagePickerControllerReferenceURL];
        }
        return nil;
}

- (NSString *)imageName
{
        NSURL *tmp = [self imageURL];
        CFUUIDRef uuidRef = CFUUIDCreate(NULL);
        CFStringRef uuidStr = CFUUIDCreateString(NULL, uuidRef);
        NSString *result = [NSString stringWithFormat:@"%@", uuidStr];
        
        CFRelease(uuidStr);
        CFRelease(uuidRef);
        
        return [NSString stringWithFormat:@"%@.%@",result,tmp.pathExtension];
}

- (NSURL *)mediaURL
{
        if ([self.allKeys containsObject:UIImagePickerControllerMediaURL]) {
                return self[UIImagePickerControllerMediaURL];
        }
        return nil;
}

- (NSDictionary *)mediaMetadata
{
        if ([self.allKeys containsObject:UIImagePickerControllerMediaMetadata]) {
                return self[UIImagePickerControllerMediaMetadata];
        }
        return nil;
}

- (FSMediaType)mediaType
{
        if ([self.allKeys containsObject:UIImagePickerControllerMediaType]) {
                NSString *type = self[UIImagePickerControllerMediaType];
                if ([type isEqualToString:(NSString *)kUTTypeImage]) {
                        return FSMediaTypePhoto;
                } else if ([type isEqualToString:(NSString *)kUTTypeMovie]) {
                        return FSMediaTypeVideo;
                }
        }
        return FSMediaTypePhoto;
}

@end


@implementation UIImage (FSMediaPicker)

- (UIImage *)circularImage
{
        // This function returns a newImage, based on image, that has been:
        // - scaled to fit in (CGRect) rect
        // - and cropped within a circle of radius: rectWidth/2
        
        //Create the bitmap graphics context
        UIGraphicsBeginImageContextWithOptions(CGSizeMake(self.size.width, self.size.height), NO, 0.0);
        CGContextRef context = UIGraphicsGetCurrentContext();
        
        //Get the width and heights
        CGFloat imageWidth = self.size.width;
        CGFloat imageHeight = self.size.height;
        CGFloat rectWidth = self.size.width;
        CGFloat rectHeight = self.size.height;
        
        //Calculate the scale factor
        CGFloat scaleFactorX = rectWidth/imageWidth;
        CGFloat scaleFactorY = rectHeight/imageHeight;
        
        //Calculate the centre of the circle
        CGFloat imageCentreX = rectWidth/2;
        CGFloat imageCentreY = rectHeight/2;
        
        // Create and CLIP to a CIRCULAR Path
        // (This could be replaced with any closed path if you want a different shaped clip)
        CGFloat radius = rectWidth/2;
        CGContextBeginPath (context);
        CGContextAddArc (context, imageCentreX, imageCentreY, radius, 0, 2*M_PI, 0);
        CGContextClosePath (context);
        CGContextClip (context);
        
        //Set the SCALE factor for the graphics context
        //All future draw calls will be scaled by this factor
        CGContextScaleCTM (context, scaleFactorX, scaleFactorY);
        
        // Draw the IMAGE
        CGRect myRect = CGRectMake(0, 0, imageWidth, imageHeight);
        [self drawInRect:myRect];
        
        UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
        UIGraphicsEndImageContext();
        
        return newImage;
}

- (UIImage *)scaleImageWithScale:(CGSize)scale
{
	CGFloat w = self.size.width;
	CGFloat h = w * (scale.height / scale.width);
	CGFloat x = 0.0;
	CGFloat y = 0.0;
	if (h < self.size.height) {
		y = (self.size.height - h) * 0.5;
	}
	
	return [self imageByCropToRect:CGRectMake(x, y, w, h)];
}

@end

const char * mediaPickerKey;

@implementation UIActionSheet (FSMediaPicker)

- (void)setMediaPicker:(FSMediaPicker *)mediaPicker
{
        objc_setAssociatedObject(self, &mediaPickerKey, mediaPicker, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}

- (FSMediaPicker *)mediaPicker
{
        return objc_getAssociatedObject(self, &mediaPickerKey);
}

@end

@implementation UIAlertController (FSMediaPicker)

- (void)setMediaPicker:(FSMediaPicker *)mediaPicker
{
        objc_setAssociatedObject(self, &mediaPickerKey, mediaPicker, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}

- (FSMediaPicker *)mediaPicker
{
        return objc_getAssociatedObject(self, &mediaPickerKey);
}


@end

@implementation UIImagePickerController (FSMediaPicker)

- (void)setMediaPicker:(FSMediaPicker *)mediaPicker
{
        objc_setAssociatedObject(self, &mediaPickerKey, mediaPicker, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}

- (FSMediaPicker *)mediaPicker
{
        return objc_getAssociatedObject(self, &mediaPickerKey);
}


@end

